home *** CD-ROM | disk | FTP | other *** search
- /* Some of the code in this file was originally based on the following file:
- * gateway.c : Paul Healy, EI9GL, 900818
- *
- * Rewrote forwarding mechanism to use "X-Forwarded-To" paradigm instead of
- * "X-BBS-To", added timer support, etc. Anders Klemets, SM0RGV, 901009.
- */
- /* Mods by G1EMM and WG7J */
- #include "global.h"
- #include "files.h"
- #include "ctype.h"
- #include "commands.h"
- #ifndef MSDOS
- #include <time.h>
- #include "ftp.h"
- #endif
- #include "bm.h"
- #include "usock.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: forward.c,v 1.49 1997/09/14 14:37:46 root Exp root $";
- #endif
-
- #ifdef MBFWD
-
- extern int MbForwarded, SYSOPprotect;
- extern char *mbxRCall;
- extern char AXRosecall[AXALEN];
-
- #ifdef XFWD
- extern int MXfwd;
- #endif
-
- #ifdef FBBFWD
- extern int Mfbb;
- #endif
-
- #ifdef LOCK
- extern int Kblocked;
- #endif
-
- extern int BBSdump;
- extern int MbBID, MbMID;
-
- #define ISPROMPT(s) (strlen(s) > 1 && s[strlen(s)-2] == '>')
- static struct timer fwdtimer;
- static int lastSessionSkipped;
- extern int FWDmode, FWDpersonal, FWDbulletins, FWDreverse, FWDinreverse;
- extern int FWDctlz;
- extern char FWDCall[AXALEN];
-
- extern char *Mbhaddress;
- extern int MbRSTYLE;
- extern char *Mbfwdinfo;
- extern char *Mbqth;
- extern char *Mbzip;
- extern int Mbsmtptoo;
- extern int UtcOffset;
- extern int MBXMaint;
- extern int MBXMaintMode;
-
- struct subchan *subchannels;
-
- #if defined(FBBCMP) && defined(UNIX)
- extern int Mfbbcmp;
- #endif
-
- #ifdef STRICT_CALL
- extern int PBBSstrict;
- #endif
-
- static void sendtempfile (FILE * newfile, struct mbx * m, int sendit);
-
- static int uselessconnect (struct mbx * m, char *filename);
- static void sendwithcorrectNL (struct mbx * m, char *str);
- void checkforALTs (void);
- static void checkoneALT (char *name);
- extern void updateFwd (char *who, char *area, long bid, long size);
- extern void ReadFwdBbs (void);
- extern void freeareas (void);
- void forwardingSummary (void);
- static char *findident (char *str, int n, char *result);
- char *mbxtime (char *line);
- static int fwdanybbs (struct mbx * m, int *poll, int *theindex);
- static void fwdtick (void *v);
- void fwdproc (int, void *, void *);
- static int isconnbbs (struct mbx * m);
- static void startfwd (int a, void *v1, void *v2);
- static int openconn (int argc, char *argv[], void *p);
- static int sendmsgtobbs (struct mbx * m, int msgn, char const *dest, int bulletin);
- static char *grabtext (char *from, char *to, int marker, int maxlen);
- extern char *nntp_name_expansion (char *name);
- extern void bid_delete (register char *string);
- int forwardreset (int argc, char *argv[], void *p);
- static int checkone (char *line, const char *str, const char *sub);
- static int adaptaddress (char *line);
- static int fwdthisarea (struct mbx * m, FILE * fwd, char *area, char *newto);
- static void fwdcleanup (struct mbx * m, const char *string);
- static int fwd_clockset (struct mbx * m);
- extern int indexFwdBbs (char *name);
- extern int makeBBSbid (char *bid, int bidlen, char *line);
- extern void bid_add (char *bid, time_t now, int tofile, char *to);
- extern int msgidcheck (char *string);
-
-
- #ifdef CATALOG
- #include "catalog.h"
-
- #define CAT forward_catalog
-
- #define forwardingtimer __STR(0)
- #define nostart __STR(1)
- #define defering __STR(2)
- #define queueing __STR(3)
- #define delayedmaintenance __STR(4)
- #define started __STR(5)
- #define unabletostart __STR(6)
- #define examining __STR(7)
- #define alreadyconnected __STR(8)
- #define checkingforfile __STR(9)
- #define forwardingcomplete __STR(10)
- #define connectionfailed __STR(11)
- #define scriptdone __STR(12)
- #define waitingfor __STR(13)
- #define Netromunavailable __STR(14)
- #define Netromsocket __STR(15)
- #define mailsent __STR(16)
- #define mailrefused __STR(17)
- #define unexpectedresponse __STR(18)
- #define forwardingmailto __STR(19)
- #define forwardfailed __STR(20)
- #define badax25iface __STR(21)
- #define nosidfound __STR(22)
- #define nosidfound2 __STR(23)
-
- #else /* CATALOG */
- static const char forwardingtimer[] = "Forwarding timer: %lu/%lu\n";
- static const char nostart[] = "Couldn't start Forwarding process";
- static const char defering[] = "fwd: Deferring large message to %s, allowed=%ld, size=%ld\n";
- static const char queueing[] = "fwd: queueing message %ld from BBS %s, to alternate: %s\n";
- static const char delayedmaintenance[] = "fwd: forward delayed - maintenance mode\n";
- static const char started[] = "fwd: forward started\n";
- static const char unabletostart[] = "fwd: unable to start new maibox\n";
- static const char examining[] = "fwd: examining '%s'\n";
- static const char alreadyconnected[] = "fwd: '%s' already connected\n";
- static const char checkingforfile[] = "fwd: checking for file '%s'\n";
- static const char forwardingcomplete[] = "PBBS forwarding complete to: %s\n";
- static const char connectionfailed[] = "fwd: Connection failed to %s, TRY = %d\n";
- static const char scriptdone[] = "fwd: %s, script done\n";
- static const char waitingfor[] = "fwd: %s, wait %ld - waiting for %s\n";
- static const char Netromunavailable[] = "fwd: Netrom route unavailable - %s\n";
- static const char Netromsocket[] = "fwd: unable to open Netrom socket - %s\n";
- static const char mailsent[] = "PBBS mail sent: %s ";
- static const char mailrefused[] = "PBBS mail refused: %s\n %s";
- static const char unexpectedresponse[] = "PBBS mail - unexpected response: %s\n %s";
- static const char forwardingmailto[] = "PBBS %sforwarding mail to: %s ";
- static const char forwardfailed[] = "PBBS forward failed: %s errno %d";
- static const char badax25iface[] = "Invalid forwarding interface '%s' for %s";
- static const char nosidfound[] = "No SID received from remote system %s - aborting";
- static const char nosidfound2[] = "'No SID' indicates a probable problem with your forwarding script";
- #endif /* CATALOG */
-
-
-
- #ifdef FBBFWD
- static char *ltoa (long value, char *string, int radix OPTIONAL);
-
- static char *
- ltoa (long value, char *string, int radix OPTIONAL)
- {
- /* assume radix of 10, since only called with that value */
- sprintf (string, "%ld", value);
- return (string);
- }
- #endif
-
-
-
- char *
- fwd_bbsname (struct mbx *m)
- {
- static char tmp[20];
-
- if (*m->call)
- (void) pax25 (tmp, m->call);
- else {
- strncpy (tmp, m->name, 19);
- (void) strupr (tmp);
- }
- return (tmp);
- }
-
-
-
- /***************************************************************************
- findident copies the 'n'th alphanumeric sequence from 'str' to result.
- It returns a ptr to result. It returns "\0" for missing identifier etc.
- Uses isalnum macro to decide on alphanumeric/non-alnum status.
- */
- static char *
- findident (char *str, int n, char *result)
- {
- int count; /* current identifier */
-
- count = 0;
- *result = '\0';
- while ((count < n) && (*str != '\0')) { /* Process alnum or non alnum seq */
- while ((*str != '\0') && (!isalnum (*str))) /* Get rid of ';:.@%"# etc */
- str++;
- if ((*str != '\0') && isalnum (*str)) { /* this is an alnum seq */
- count++;
- while ((*str != '\0') && (isalnum (*str) || (*str == '_')))
- if (count == n)
- *result++ = *str++;
- else
- str++;
- if (count == n)
- *result = '\0';
- }
- }
- return result;
- }
-
-
- extern int Mbfullsvc;
-
-
-
- static int
- checkone (char *line, const char *str, const char *sub)
- {
- char *cp;
-
- if (str && line && !strnicmp (line, str, strlen (str)) && (cp = strstr (line, Hostname)) != NULLCHAR) {
- strcpy (cp, sub);
- return 1;
- }
- return 0;
- }
-
-
-
- static int
- adaptaddress (char *line)
- {
- char buf[60], *cp;
-
- (void) pax25 (buf, Mycall);
- if ((cp = strpbrk (buf, DIGI_IDS)) != NULLCHAR)
- *cp = '\0'; /* remove SSID */
- if (Mbhaddress != NULLCHAR) {
- strcat (buf, ".");
- strcat (buf, Mbhaddress);
- }
- strcat (buf, "\n");
- if (checkone (line, Hdrs[XMAILGROUP], buf))
- return 1;
- if (checkone (line, Hdrs[ERRORSTO], buf))
- return 1;
- return (checkone (line, Hdrs[REPLYTO], buf));
- }
-
-
-
- static void
- sendwithcorrectNL (struct mbx *m, char *str)
- {
- #if defined(UNIX) && defined(FBBCMP)
- if (m->msglst && Mfbbcmp && m->sid & MBX_FBBCMP) {
- rip (str);
- strcat (str, "\r\n");
- }
- #endif
- fputs (str, m->quickfile);
- }
-
-
-
- /**************************************************************************/
- /* sendmsg() modified to send the R: line always.
- * also added some additional strings like qth and zipcode etc. to R: line.
- * Original SMTP headers get forwarded optionally.
- * 920114 - WG7J
- */
-
- void
- sendmsg (struct mbx *m, int msgn, char *thebid)
- {
- FILE *oldfile, *newfile;
- char buf[LINELEN], tb[LINELEN], *cp;
- char Rline[LINELEN];
- int rec = 0; /* rec is line-counter */
- unsigned int msgid = 0; /* message id number - WG7J */
- int col, ccnt;
- char c;
- int sendthefile = 0;
- long endofmsg = 0L;
-
- /* point to start and end of this message in file */
- fseek (m->mfile, m->mbox[msgn].start, 0);
- if (m->nmsgs > msgn)
- endofmsg = m->mbox[msgn + 1].start;
-
- /* If the data part of the message starts with "R:" the RFC-822
- * headers will not normally be forwarded. Instead we will add an R:
- * line of our own. ALWAYS forward with "R:" line
- */
-
- /* This loop is until we have read our internal MID */
- for (;;) {
- /* read a line */
- if (fgets (buf, sizeof (buf), m->mfile) == NULLCHAR)
- break;
- kwait (NULL);
-
- if (rec == 1) { /* We are on the line with the MID */
- /* look at the line following Received:
- * This has the ID followed by ' ; date&time in arpa-format'
- * Get the message number from the ID line - WG7J
- */
- if ((cp = strstr (buf, "AA")) != NULLCHAR)
- /* what follows is the message-number */
- msgid = (unsigned int) atoi (cp + 2);
-
- /* get the ARPA format date/time string */
- if ((cp = strchr (buf, ';')) != NULLCHAR)
- strncpy (tb, cp + 1, LINELEN); /* point to the date of receipt */
-
- /* Get the callsign for the R: line */
- if (mbxRCall)
- strncpy (buf, mbxRCall, LINELEN);
- else
- (void) pax25 (buf, Mycall);
- if ((cp = strpbrk (buf, DIGI_IDS)) != NULLCHAR)
- *cp = '\0'; /* remove SSID */
-
- /* If not a fullservice BBS, don't send the R: line */
- if (Mbfullsvc) {
- if (!MbRSTYLE) {
- sprintf (Rline, "R:%s @:%s%s%s ", mbxtime (tb), buf,
- (Mbhaddress != NULLCHAR) ? "." : "",
- (Mbhaddress != NULLCHAR) ? Mbhaddress : "");
- if (Mbfwdinfo)
- sprintf (&Rline[strlen (Rline)], "[%s] ", Mbfwdinfo);
- if (Mbqth)
- sprintf (&Rline[strlen (Rline)], "%s ", Mbqth);
- if (MbMID)
- sprintf (&Rline[strlen (Rline)], "#:%u ", msgid);
- if (Mbzip)
- sprintf (&Rline[strlen (Rline)], "Z:%s ", Mbzip);
- if (MbBID)
- sprintf (&Rline[strlen (Rline)], "$:%s", thebid);
- strcat (Rline, "\n");
- } else
- sprintf (Rline, "R:%s %d@%s%s%s\n", mbxtime (tb), msgid, buf,
- (Mbhaddress) ? "." : "", (Mbhaddress) ? Mbhaddress : "");
- #ifdef BBSEXPORT
- if (m->quickfile)
- sendwithcorrectNL (m, Rline);
- else
- #endif
- usputs (m->user, Rline);
- } /* Mbfullsvc */
- break; /* done with this portion of the message */
- } /* rec == 1 */
- /* The first Received: line is the one that we have added */
- if (!rec && htype (buf) == RECEIVED)
- ++rec;
- }
-
-
- /* Go past the SMTP headers to the data of the message.
- * Check if we need to forward the SMTP headers! 920114 - WG7J
- */
-
-
- /* first, save any current quickfile, and replace it with a tmpfile
- * for placing any smtp headers into.
- */
- oldfile = m->quickfile;
- newfile = tmpfile ();
- m->quickfile = newfile;
-
- /* place the separating NL */
- #if defined(UNIX) && defined(FBBCMP)
- if (m->msglst && Mfbbcmp && m->sid & MBX_FBBCMP)
- fputs ("\r\n", m->quickfile);
- else
- #endif
- fputs ("\n", m->quickfile);
-
-
- /* This loop is to process the RFC headers and send any needed ones
- * to a TEMP file, to be inserted at the proper time.
- */
- for (;;) {
- if (fgets (buf, sizeof (buf), m->mfile) == NULLCHAR)
- break;
- kwait (NULL);
- if (*buf == '\n') /* last header line */
- break;
- if (adaptaddress (buf)) { /* check for headers always sent */
- sendwithcorrectNL (m, buf);
- sendthefile = 1;
- } else if (Mbsmtptoo) {
- /* YES, forward SMTP headers TOO !*/
- switch (htype (buf)) {
- case XFORWARD: /* Do not forward the "X-Forwarded-To:" lines */
- case STATUS: /* Don't forward the "Status:" line either */
- case BBSTYPE:
- case SUBJECT:
- case TO:
- case DATE:
- /* never send these headers */
- break;
- case FROM: /* Don't forward the "From: " line either, make it ">From: " */
- cp = strdup (buf);
- strcpy (buf, ">");
- strcat (buf, cp);
- free (cp);
- /* note fall-through */
- default:
- trimrightCR (buf);
- sendwithcorrectNL (m, buf);
- sendthefile = 1;
- } /* switch */
- } /* Mbsmtptoo */
- } /* for */
-
- /* Now reset the quickfile to it's previous state and rewind tempfile */
- m->quickfile = oldfile;
- if (newfile)
- rewind (newfile);
-
- /* If there are other R: headers, process them first */
- for (;;) { /* do this while you have R: lines */
- /* if there is no data, send the tempfile and you're done */
- if (fgets (buf, sizeof (buf), m->mfile) == NULLCHAR) {
- sendtempfile (newfile, m, sendthefile);
- return; /* NO text ??? */
- }
- if (strncmp (buf, "R:", 2)) /* No more R: lines! */
- break;
- #ifdef BBSEXPORT
- if (m->quickfile)
- sendwithcorrectNL (m, buf);
- else
- #endif
- usputs (m->user, buf);
- }
-
- /* Now add the smtp headers desired. */
- sendtempfile (newfile, m, sendthefile);
-
- if (!strncmp (Hdrs[RRECEIPT], buf, strlen (Hdrs[RRECEIPT]))) { /* return receipt line */
- if (!isarea (m->area)) { /* only send if not a bulletin */
- #ifdef BBSEXPORT
- if (m->quickfile)
- sendwithcorrectNL (m, buf);
- else
- #endif
- usputs (m->user, buf);
- }
- (void) fgets (buf, sizeof (buf), m->mfile); /* eat the blank line following */
- if (*buf == '\n')
- (void) fgets (buf, sizeof (buf), m->mfile); /* eat the blank line following */
- }
- /* place the separating NL */
- #ifdef BBSEXPORT
- #if defined(UNIX) && defined(FBBCMP)
- if (m->quickfile) {
- if (m->msglst && Mfbbcmp && m->sid & MBX_FBBCMP)
- fputs ("\r\n", m->quickfile);
- else
- #else
- if (m->quickfile) {
- #endif
- fputs ("\n", m->quickfile);
- } else
- #endif
- usputs (m->user, "\n");
-
- /* we now have the first data line in buf, so send it */
- #ifdef BBSEXPORT
- if (m->quickfile)
- sendwithcorrectNL (m, buf);
- else
- #endif
- usputs (m->user, buf);
-
-
-
- /* the rest of the message is treated below */
- col = 0;
- while (!feof (m->mfile)) {
- if (endofmsg && (ftell (m->mfile) >= endofmsg))
- break;
- for (col = 0; col < MAXBUF;) {
- c = (char) getc (m->mfile);
- if (feof (m->mfile)) /* end this line */
- break;
- if (c == '\t') {
- ccnt = col + 8 - (col & 7);
- if (ccnt >= MAXBUF) /* end this line */
- break;
- while (col < ccnt)
- buf[col++] = ' ';
- } else {
- if (c == '\n')
- break;
- buf[col++] = c;
- }
- } /* for */
- if (col < MAXBUF)
- buf[col++] = '\n';
- buf[col] = '\0';
-
- if (!strncmp (buf, "From ", 5)) /* somehow endofmsg didn't work */
- break;
- #ifdef BBSEXPORT
- if (m->quickfile)
- sendwithcorrectNL (m, buf);
- else
- #endif
- usputs (m->user, buf);
- kwait (NULL);
- } /* while */
- }
-
-
-
- static void
- sendtempfile (FILE *newfile, struct mbx *m, int sendit)
- {
- int c;
-
- if (sendit) {
- #ifdef BBSEXPORT
- if (m->quickfile) {
- while ((c = getc (newfile)) != EOF)
- fputc (c, m->quickfile);
- } else
- #endif
- (void) sendfile (newfile, m->user, ASCII_TYPE, 0);
- }
- (void) fclose (newfile);
- }
-
-
-
- /* Parse a line for date and time in Arpanet format
- * (Day, day Month year hh:mm:ss Zone) and return it in mailbox format
- * (yymmdd/hhmmz)
- */
- char *
- mbxtime (char *line)
- {
- static char buf[13];
- char *cp;
- int year, month, day, hour, minute, maxdays;
-
- cp = line;
- if (!cp)
- return NULLCHAR;
- while (isspace (*cp)) /* skip initial blanks */
- ++cp;
- if (*cp == '\0')
- return NULLCHAR;
- if (strlen (cp) < 22)
- return NULLCHAR;
- cp += 5;
- day = atoi (cp);
- if (*(++cp) != ' ')
- ++cp;
- ++cp;
- for (month = 0; month < 12; ++month)
- if (strnicmp (Months[month], cp, 3) == 0)
- break;
- if (month == 12)
- return NULLCHAR;
-
- /* Get things, and adjust for GMT/UTC time - WG7J */
- month++;
- year = atoi (cp + 4);
- hour = atoi (cp + 7);
- minute = atoi (cp + 10);
-
- if (UtcOffset != 0) {
- hour -= UtcOffset;
- /* See if we went past midnight */
- if (hour > 23) {
- hour -= 24;
- ++day;
- /*Check for next month*/
- if (month == 2) { /*February, check leap-year*/
- if ((year % 4) == 0)
- maxdays = 29;
- else
- maxdays = 28;
- } else {
- if ((month % 2) == 0)
- maxdays = 30;
- else
- maxdays = 31;
- }
- if (day > maxdays) { /*adjust month*/
- day = 1;
- if (++month == 13) { /*next year*/
- month = 1;
- year++;
- }
- }
- } else if (hour < 0) { /*previous day !*/
- hour += 24;
- if (--day == 0) { /*previous month*/
- if (--month == 0) { /*previous year*/
- year--;
- month = 12;
- }
- if (month == 2) { /* February, check leap year */
- if ((year % 4) == 0)
- day = 29;
- else
- day = 28;
- } else {
- if ((month % 2) == 0)
- day = 30;
- else
- day = 31;
- }
- }
- }
- }
- sprintf (buf, "%02d%02d%02d/%02d%02dz", year, month, day, hour, minute);
- return buf;
- }
-
-
-
- static char *
- grabtext (char *from, char *to, int marker, int maxlen)
- {
- while (*from != marker) {
- *to++ = *from++;
- if (!--maxlen)
- break;
- }
- *to = '\0';
- return from + 1;
- }
-
-
-
- /* Makes a command line and returns -1 if the message cannot be sent and
- -2 if message couldn't be sent and should be deleted.
- */
- int
- makecl (m, msgn, dest, line, subj, bid, bul)
- struct mbx *m;
- int msgn; /* Message number */
- char const *dest; /* Destination address to use instead of To: line */
- char *line, *subj; /* Buffers to keep command line and subject */
- char *bid; /* Buffer to keep bid */
- int *bul; /* True if message is in public message area */
- {
- int bulletin = *bul;
- int foundbid = 0;
- int foundmid = 0;
- char to[LINELEN], atbbs[LINELEN], from[LINELEN], buf[LINELEN], *cp;
- #ifdef FBBFWD
- char bid2[LINELEN];
- char tmp[40];
- #endif
-
- if (m->mfile == NULLFILE)
- return -1;
-
- /* used to be if(!bulletin && (m->mbox[msgn].status & BM_READ)) */
- if (!issysarea (m->area) && (m->mbox[msgn].status & BM_READ))
- return -2; /* the message was already read */
- fseek (m->mfile, m->mbox[msgn].start, 0);
- *bid = *to = *atbbs = *from = '\0';
- if (subj != NULLCHAR)
- *subj = '\0';
- m->stype = bulletin ? 'B' : 'P'; /* default to SB or SP */
- /* if it comes from a NTS area, always send as traffic, ie 'ST' - WG7J */
- if (!strnicmp (m->area, "nts", 3))
- m->stype = 'T';
- while (fgets (buf, sizeof (buf), m->mfile)) {
- if (buf[0] == '\n')
- break; /* envelope finished */
- switch (htype (buf)) {
- case TO:
- trimrightCR (buf);
- /* The following code tries to parse "To: " lines where the
- * address looks like any of the following: "to@atbbs",
- * "<to@atbbs>", "<to%atbbs@host>" and with possible spaces
- * surrounding the '<>' characters.
- */
- if ((cp = getaddress (buf, 0)) == NULLCHAR)
- break;
- strncpy (to, cp, LINELEN);
- if ((cp = strchr (to, '%')) != NULLCHAR) { /* look for a '%' */
- strncpy (atbbs, cp + 1, LINELEN);
- *cp = '\0'; /* "to" ends at the '%' character */
- if ((cp = strchr (atbbs, '@')) != NULLCHAR)
- *cp = 0;
- } else { /* no '%' but maybe a '@'? */
- if ((cp = strchr (to, '@')) != NULLCHAR) {
- strncpy (atbbs, cp + 1, LINELEN);
- *cp = '\0'; /* "to" ends at the '@' character */
- }
- }
-
- /* "to" or "atbbs" should not be more than 6 characters (ALEN).
- * If "to" is too long, it might simply be because the area name
- * is longer than 6 characters, but it might also be because
- * the address on the To: line is in an obscure format that we
- * failed to parse (eg '!' character notation.)
- */
- if (strlen (to) > ALEN) {
- #if 0
- /* Play safe and set "to" and "atbbs" to the area name */
- strncpy (to, m->area, LINELEN);
- strncpy (atbbs, m->area, LINELEN);
- #else
- /* if "to" or "atbbs" are > 6 character, they are IMPROPER. Delete them */
- return -2;
- #endif
- }
- /* why would we want to add an atbbs if the message doesn't have one originally ?!?! */
- #if 0
- if (*atbbs == '\0')
- strncpy (atbbs, to, LINELEN);
- #endif
-
- to[ALEN] = '\0';
- /* Only if the BBS supports "hierarchical routing designators"
- * is the atbbs field allowd to be longer than 6 characters and
- * have dots in it.
- */
- if ((m->sid & MBX_HIER_SID) == 0) {
- atbbs[ALEN] = '\0'; /* 6 character limit */
- if ((cp = strchr (atbbs, '.')) != NULLCHAR)
- *cp = '\0'; /* cut "atbbs" at first dot */
- }
- break;
- case MSGID:
- if (!foundmid) {
- foundmid = 1;
- trimrightCR (buf);
- bid[0] = '$';
- foundbid = makeBBSbid (&bid[1], LINELEN - 1, buf);
- /* if a bulletin and not in the history file, add it */
- if (*bul && !msgidcheck (&bid[1]))
- bid_add (&bid[1], time ((time_t *)0), 1, m->area);
- }
- break;
- case SUBJECT:
- trimrightCR (buf);
- if (subj != NULLCHAR) {
- if (buf[8] != '\n')
- (void) grabtext (buf + 9, subj, '\n', LINELEN - 1);
- /* Make sure subject isn't empty - WG7J */
- cp = subj;
- while (*cp == ' ' || *cp == '\t')
- cp++;
- if (*cp == '\0')
- strcpy (subj, "None");
- }
- break;
- case FROM:
- trimrightCR (buf);
- if ((cp = getaddress (buf, 0)) != NULLCHAR) {
- if (!strnicmp (cp, "REQSVR", 6) || !strnicmp (cp, "MAILER-DAEMON", 13)) { /* MAILER-DAEMON going out->call sign */
- (void) pax25 (buf, Mycall);
- cp = strpbrk (buf, DIGI_IDS);
- if (cp)
- *cp = 0;
- strncpy (from, buf, LINELEN);
- } else
- (void) findident (cp, 1, from); /* cp points to from@domain */
- from[ALEN] = '\0'; /* 6 character limit */
- }
- break;
- case XFORWARD:
- if ((cp = getaddress (buf, 0)) == NULLCHAR)
- break;
- if (stricmp (m->name, cp) == 0) {
-
- /* This message was RECEIVED from this BBS, abort */
- return -2;
- }
- break;
- case BBSTYPE:
- if (m->stype == 'P') {
- /* we do not make messages in public areas into personals
- * but the reverse is permitted
- */
- m->stype = buf[16];
- if (m->stype == 'B')
- bulletin = *bul = 1;
- else
- bulletin = *bul = 0;
- }
- break;
- default:
- break;
- }
- }
- /* Check for an invalid RFC-822 header */
- if ((to[0] == '\0' && ((dest != NULLCHAR && *dest == '\0') ||
- dest == NULLCHAR)) || from[0] == '\0')
- return -2;
-
- #ifdef STRICT_CALL
- if (PBBSstrict && strcasecmp(from, "WP") && !iscall (from))
- return -2;
- #endif
-
- if (line != NULLCHAR) {
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD)) {
- if (*atbbs) {
- strncpy (tmp, atbbs, 39);
- tmp[39] = 0;
- } else if (*m->call) {
- /* outgoing, we canNOT be sure m->name is correct!
- The BBS name in forward.bbs (which is m->name)
- does NOT need to be the BBS name, so we look at
- the callsign, instead... */
- (void) pax25 (tmp, m->call);
- if ((cp = strpbrk (tmp, DIGI_IDS)) != NULLCHAR)
- *cp = 0;
- } else {
- strncpy (tmp, m->name, 39);
- tmp[39] = 0;
- }
- }
- #endif
- if (dest != NULLCHAR && *dest != '\0') {
- char *tempcp = strdup (dest);
-
- /* strip off hierarchical routing designators from the predefined
- * destination address if they are not supported
- */
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD)) {
- if ((cp = strchr (tempcp, '.')) != NULLCHAR)
- *cp = '\0';
- if ((cp = strchr (tempcp, '@')) != NULLCHAR)
- *cp = '\0';
- sprintf (line, "FA %c %s %s %s ", m->stype, from, (cp) ? (cp + 1) : tmp, tempcp);
- } else {
- #endif
- if ((m->sid & MBX_HIER_SID) == 0 && (cp = strchr (tempcp, '.')) != NULLCHAR)
- *cp = '\0';
- sprintf (line, "S%c %s < %s ", m->stype, tempcp, from);
- #ifdef FBBFWD
- }
- #endif
- free (tempcp);
- } else {
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD))
- sprintf (line, "FA %c %s %s %s ", m->stype, from, tmp, to);
- else
- #endif
- sprintf (line, "S%c %s%s%s < %s ", m->stype, to, (*atbbs) ? " @ " : "", atbbs, from);
- }
- #ifdef nope
- /* This fixes the problem with personal MIDs being the same with
- * messages generated from aliases, RMAIL, or mail-groups. Changes
- * the bid from $abcde_host.domain to $abcde_destinationuser. - KO4KS
- */
- if (!bulletin && (m->sid & MBX_MID)) {
- if ((cp = strrchr (bid, '_')) != NULLCHAR) {
- *cp++;
- if (!strnicmp (Hostname, cp, strlen (cp))) {
- *(cp - 1) = '%';
- if (dest != NULLCHAR && *dest != '\0')
- strcpy (cp, dest);
- else
- strcpy (cp, to);
- bid[13] = '\0';
- if ((cp = strchr (bid, '.')) != NULLCHAR)
- *cp = '\0';
- }
- }
- }
- #endif
-
- /* This keeps us from adding a MID to someone else's message */
- if (!foundbid) {/* if one wasn't found, but GENERATED */
- (void) fgets (buf, sizeof (buf), m->mfile); /* get first data line */
- if (!strnicmp (buf, "R:", 2)) /* if it has at least one "R:" line */
- bid[0] = '\0'; /* blank out the MID */
- }
- /* convert the bid to upper case for compatability with BBSs */
- (void) strupr (bid);
-
- /* Add the bid to bulletins,
- * AND ALSO to anything that came in with a bid !
- * Takes care off duplicate 'SP SYSOP@xxx $BID' problems - WG7J
- * ALSO add it to ALL messages if the remote system supports MID's - WG7J
- */
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD) &&
- ((m->sid & MBX_MID) || (bulletin && (m->sid & MBX_SID))))
- /* Append BID ( minus the '$' character. */
- strcat (line, &bid[1]);
- else
- #endif
- /* if((m->sid & MBX_MID) || ((bulletin || foundbid) & (m->sid & MBX_SID))) */
- if ((m->sid & MBX_MID) || (bulletin && (m->sid & MBX_SID)))
- strcat (line, bid);
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD)) {
- strcat (line, " ");
- strcat (line, (char *) ltoa (m->mbox[msgn].size, bid2, 10));
- }
- #endif
- strcat (line, "\n");
- }
- return 0;
- }
-
-
-
- static int /* 0 = ok, -1 = problem so disc */
- sendmsgtobbs (m, msgn, dest, bulletin)
- struct mbx *m;
- int msgn;
- char const *dest; /* Optional destination address to override To: line */
- int bulletin;
- {
- int result = -1;
- char line[LINELEN], subj[LINELEN], thebid[LINELEN];
-
- if (makecl (m, msgn, dest, line, subj, thebid, &bulletin) < 0)
- return 0; /* do not forward this particular message */
-
- if (thebid[0] == 0) {
- if (Mtrace)
- tcmdprintf ("FWD: Skipping message to %s without a BID: %s\n", fwd_bbsname (m), line);
- log (m->user, "Skipping message to %s without a BID: %s\n", fwd_bbsname (m), line);
- return 0;
- }
- if (Mtrace)
- tcmdprintf ("FWD: Sending to %s - %s.\n", fwd_bbsname (m), line);
-
- #ifdef BBSEXPORT
- if (m->quickfile) {
- fputs (line, m->quickfile);
- m->line[0] = 'O';
- } else {
- #endif
- tputs (line); /* Send mail offer to bbs */
- usflush (m->user);
- #ifdef BBSEXPORT
- }
- #endif
- rip (line);
- if (m->quickfile || recvline (m->user, (unsigned char *) m->line, MBXLINE) != -1) {
- if (Mtrace)
- tcmdprintf ("FWD: Received from %s - %s.\n", fwd_bbsname (m), m->line);
-
- if (m->line[0] == 'O' || m->line[0] == 'o' || (m->sid & MBX_SID) == 0) {
- if (Mtrace)
- tcmdprintf ("FWD: Sending message to %s\n", fwd_bbsname (m));
- /* Got 'OK' or any line if the bbs is unsofisticated */
- #ifdef BBSEXPORT
- if (m->quickfile)
- fprintf (m->quickfile, "%s\n", subj);
- else
- #endif
- tprintf ("%s\n", subj);
- sendmsg (m, msgn, &thebid[1]); /* send the message */
- #ifdef BBSEXPORT
- if (m->quickfile) {
- fputs ("/EX\n", m->quickfile);
- strcpy (m->line, "> ");
- } else {
- #endif
- if (FWDctlz)
- tputs ("\032\n");
- else
- tputs ("/EX\n");
- usflush (m->user);
- #ifdef BBSEXPORT
- }
- #endif
- /* get '>' for a good deliver */
- while (m->quickfile || recvline (m->user, (unsigned char *) m->line, MBXLINE) != -1)
- if (ISPROMPT (m->line)) {
- log (m->user, mailsent, line);
- if (!bulletin && (stricmp (m->area, "sysop") || !SYSOPprotect)) {
- m->mbox[msgn].status |= BM_DELETE;
- statusCtl (m->area, "ctl", &m->mbox[msgn], msgn, 0);
- m->change |= CHG_DELETE;
- }
- result = 0;
- MbForwarded++;
- break;
- }
- } else { /* OK response not received from bbs */
- if (tolower (m->line[0]) == 'n' || tolower (m->line[0]) == 'r') { /* 'NO/REJECT' response */
- log (m->user, mailrefused, line, m->line);
- result = 0; /* don't want it, so skip it! */
- } else
- log (m->user, unexpectedresponse, line, m->line);
-
- /* should get a F> here */
- while (recvline (m->user, (unsigned char *) m->line, MBXLINE) != -1)
- if (ISPROMPT (m->line)) {
- result = 0;
- break;
- }
- }
- } /* OK or NO here */
- if (m->stype != 'B')
- bid_delete (&thebid[1]);
- return result;
- }
-
-
-
- void
- mark_forwarded (FILE *fp, long ind, char thetype)
- {
- long save;
-
- clearerr (fp);
- save = ftell (fp);
- fseek (fp, ind, SEEK_SET);
- fputc (thetype, fp); /* mark as done! */
- (void) fflush (fp);
- fseek (fp, save, SEEK_SET);
- }
-
-
-
- /* Forward messages from one message area. */
- static int
- fwdthisarea (struct mbx *m, FILE *fwd, char *area, char *newto)
- {
- int bulletin;
- long bid, pos = 0;
- int theindex, changed = 0, i;
- int err = 0;
- char *cp;
- struct let *cmsg;
- char line[80];
-
-
- kwait (NULL);
- bulletin = isarea (area); /* public area */
-
- if (Mtrace && FWDareatrace)
- tcmdprintf ("FWD: Processing %s message area %s for %s.\n",
- bulletin ? "Public " : "Private ", area, fwd_bbsname (m));
-
- if (bulletin && (!FWDbulletins || !m->fwdbbs->bulletins))
- return err;
- if (!bulletin && (!FWDpersonal || !m->fwdbbs->personals))
- return err;
- rewind (fwd);
- while (!err && fgets (line, sizeof (line), fwd) != NULLCHAR) {
- (void) fflush (fwd);
- kwait (NULL);
- if (*line == ' ') { /* if not already done or blocked */
- if ((cp = strpbrk (&line[1], " \t")) == NULLCHAR)
- continue;
- *cp++ = '\0';
- if (!stricmp (area, &line[1])) { /* only if for us */
- bid = atol (cp);
- if (!changed) { /* if not already changed */
- m->area[0] = 0; /* force a reload of index */
- changearea (m, area, (int) 1);
- changed = 1;
- }
- theindex = 0;
- for (cmsg = &m->mbox[1], i = 1; i <= m->nmsgs; i++, cmsg++)
- if ((bid == cmsg->bid) && !(cmsg->status & BM_DELETE)) {
- theindex = i;
- break;
- }
- if (theindex && m->fwdbbs && m->fwdbbs->maxsize && cmsg->size > m->fwdbbs->maxsize) {
- if (Mtrace)
- tcmdprintf (defering, m->fwdbbs->name, m->fwdbbs->maxsize, cmsg->size);
- } else {
- if (theindex && !(cmsg->status & (BM_ONHOLD | BM_DELETE))) {
- mark_forwarded (fwd, pos, '!');
- if (sendmsgtobbs (m, theindex, newto, bulletin) == -1)
- err = 1; /* abort */
- else {
- #ifdef STATS_MSG
- STATS_addmsg (1, 1);
- #endif
- #ifdef STATS_TFC
- STATS_addtfc (3, 1);
- #endif
- #ifdef STATS_FWD
- STATS_addfwd (1, 1, m->name);
- #endif
- }
- }
- if (!theindex || (!err && !(cmsg->status & BM_ONHOLD)))
- mark_forwarded (fwd, pos, '*');
- }
- }
- }
- pos = ftell (fwd); /* get new backup position */
- if (MBXMaintMode && MBXMaint)
- break;
- }
- return err;
- }
-
-
-
- /* This is the main entry point for reverse forwarding. It is also used
- * for normal, "forward", forwarding.
- */
- int
- dorevfwd (int argc OPTIONAL, char *argv[] OPTIONAL, void *p)
- {
- char oldarea[64], *area, *cp;
- struct mbx *m;
- int err = 0;
- FILE *fwd;
- long thesize, theend, newsize;
- char name[256];
- struct arealist *a;
-
- m = (struct mbx *) p;
- /* indicate we are doing reverse forwarding, if we are not already
- * doing normal forwarding.
- */
- if (m->state != MBX_FORWARD) {
- if (!FWDreverse)
- goto notallowed;
- m->state = MBX_REVFWD;
- if ((m->sid & MBX_SID) && m->mysize)
- smtptick (NULL); /* wake SMTP to send that mail */
- m->mysize = 0;
- }
- if (m->fwdbbs || fwdinit (m, 1) != -1) {
- strncpy (oldarea, m->area, 64);
- sprintf (name, "%s/%s", Mailspool, m->name);
- (void) nntp_name_expansion (name);
- strcat (name, ".fwd");
- (void) strlwr (name);
- if ((fwd = fopen (name, UPDATE_TEXT)) == NULLFILE)
- return 0; /* shouldn't happen except with reverse fwd */
- log (m->user, forwardingmailto, (m->state == MBX_REVFWD) ? "reverse " : "", m->name);
- thesize = (long) filelength (fileno (fwd)); /* so we know if any new */
-
- a = m->fwdbbs->areas;
- if (m->fwdbbs->noreverseincoming)
- m->usecolor = 0;
- if (m->state != MBX_FORWARD)
- if (checksubchannel (m, 1))
- err = 1;
-
- while (!err) {
- if (cutofffwding (m))
- break;
- if (m->privs & EXCLUDED_CMD)
- break;
- newsize = (long) filelength (fileno (fwd));
- if (thesize != newsize) {
- /* if new mail came in to forward, start back
- up at the top of the areas to forward.
- This allows you to push personal traffic
- at highest priority */
- thesize = newsize;
- a = m->fwdbbs->areas;
- }
- if (a == NULLAREALIST)
- break;
-
- cp = strdup ((a->forceaddr) ? a->forceaddr : "");
- area = strdup (a->name);
- a = a->next;
- err = fwdthisarea (m, fwd, area, cp);
- if (MBXMaintMode && MBXMaint)
- break;
- free (cp);
- free (area);
- }
-
- if (*oldarea != '\0')
- changearea (m, oldarea, (int) 1);
- fwdlockit (m->name);
- theend = (long) filelength (fileno (fwd));
- if (!err && thesize == theend) {
- rewind (fwd);
- while (newsize = ftell (fwd), fgets (m->line, MBXLINE, fwd) != NULLCHAR) {
- kwait (NULL);
- if (*m->line == '=') {
- mark_forwarded (fwd, newsize, '!');
- err = 1;
- } else if (*m->line == '!') {
- mark_forwarded (fwd, newsize, ' ');
- err = 1;
- } else if (*m->line != '*' && *m->line != '-') { /* if not already done */
- err = 1;
- #if 0
- break;
- #endif
- }
- }
- (void) fclose (fwd);
- if (!err)
- (void) remove (name);
- } else
- (void) fclose (fwd);
- fwdunlockit (m->name);
- }
- if (m->state != MBX_FORWARD)
- releasesubchannel (m);
- if (m->state == MBX_FORWARD)
- return err;
- notallowed:
- /* This section marks the last fwd session time */
- if ((err = indexFwdBbs (fwd_bbsname (m))) != NUMFWDBBS) {
- MyFwds[err].laston = time (NULL);
- MyFwds[err].lastactivity = time (NULL);
- }
- tputs ("*** Done\n");
- tflush ();
- if (m->sid & MBX_RLI_SID) /* disconnect if it is a W0RLI bbs */
- return domboxbye (0, NULL, m);
- return 0;
- }
-
-
-
- void
- releasesubchannel (struct mbx *m)
- {
- if (m->subchannel != NOSUBCHANNEL) {
- if (subchannels[m->subchannel].used)
- subchannels[m->subchannel].used--;
- m->subchannel = NOSUBCHANNEL;
- }
- }
-
-
-
- /* Check to see if there is room in the subchannel tables for this BBS,
- * *IF* they are suppose to use a subchannel. This routine also is used
- * to assign the subchannel, if desired. Returns 0 if subchannel is available,
- * -1 if it is NOT available.
- */
- int
- checksubchannel (struct mbx *m, int assignit)
- {
- int i;
-
- i = m->fwdbbs->subchannel;
-
- /* return OK if no subchannel is to be used */
- if (i == NOSUBCHANNEL)
- return 0;
-
- /* return OK if subchannel already assigned to this BBS */
- if (i == m->subchannel)
- return 0;
-
- /* Now check if there is room on this subchannel */
- if (i > NUMMBX || subchannels[i].used >= (int) subchannels[i].limit)
- return -1; /* nope */
-
- /* Now we assign the subchannel slot to this BBS, if desired */
- if (assignit) {
- subchannels[i].used++;
- m->subchannel = i;
- }
- return 0;
- }
-
-
-
- static int
- uselessconnect (struct mbx *m, char *filename)
- {
- int retval = -1;
- FILE *fp;
- char buf[255], *cp;
- int foundone = 0, i;
- long bid;
- struct let *cmsg;
- int anyvalid = 0;
-
- if (!access (filename, 0)) {
- if ((fp = fopen (filename, "r")) != NULLFILE) {
- while (fgets (buf, 255, fp)) {
- /* if forwarded, skip it (no valid message, here) */
- if (*buf == '*')
- continue;
-
- /* if passed to an alt, skip it (valid message, though) */
- if (*buf == '-') {
- anyvalid = 1;
- continue;
- }
-
- if ((cp = strchr (&buf[1], ' ')) == NULLCHAR)
- continue; /* syntax error */
- *cp++ = 0;
- /* get internal id number of message */
- bid = atol (cp);
- changearea (m, &buf[1], (int) 0);
- for (cmsg = &m->mbox[1], i = 1; i <= m->nmsgs; i++, cmsg++)
- /* find the message we're supposed to forward. */
- if (bid == cmsg->bid) {
- if (!(cmsg->status & (BM_DELETE | BM_ONHOLD))) {
- /* this is the message... set the flag and break. */
- foundone = 1;
- break;
- } else if (!(cmsg->status & BM_DELETE)) {
- /* not deleted, just on hold (valid message) */
- anyvalid = 1;
- }
- }
- if (foundone) {
- retval = 0;
- break;
- }
- }
- (void) fclose (fp);
- }
- if (!foundone) {
- if (Mtrace)
- tcmdprintf ("fwd: no available traffic found - skipping useless connect to %s\n", m->fwdbbs->name);
- if (!anyvalid) {
- /* if all messages are fwded or deleted, then remove the file */
- (void) remove (filename);
- if (Mtrace)
- tcmdprintf ("fwd: no remaining traffic found - removing forward file for %s\n", m->fwdbbs->name);
- }
- }
- }
- return retval;
- }
-
-
-
- /* Read the forward file for a record for the connected BBS. If found,
- * return 0 if this is the right time to forward, m->tfile is left pointing
- * at the first message area to be forwarded.
- * returns -1, also, if nothing queued for forwarding.
- */
- int
- fwdinit (struct mbx *m, int try)
- {
- int retval = -1;
- char name[256];
-
- fwdfree (&m->fwdbbs);
- m->fwdbbs = fwdread (m->name, try);
- if (m->fwdbbs != NULLFWDBBS && m->fwdbbs->conn) {
- sprintf (name, "%s/%s", Mailspool, m->fwdbbs->name);
- (void) nntp_name_expansion (name);
- strcat (name, ".fwd");
- (void) strlwr (name);
- if (m->special || m->fwdbbs->poll)
- retval = 0;
- else
- retval = uselessconnect (m, name);
- }
- if (!retval)
- retval = checksubchannel (m, 0);
- return retval;
- }
-
-
-
- /* Read the forward file for a record for the connected BBS. If found,
- * determine if this is the right time to forward, and return the command
- * line to establish a forwarding connection. m->tfile is left pointing
- * at the first message area to be forwarded.
- */
- static int
- fwdanybbs (struct mbx *m, int *poll, int *theindex)
- {
- int k;
- int done = 0;
- int retval = 0;
-
- *poll = 0; /* Default to no polling */
-
- fwdfree (&m->fwdbbs);
-
- do {
- m->fwdbbs = fwdread (NULLCHAR, *theindex++);
- if (m->fwdbbs == NULLFWDBBS) {
- done = 1;
- continue;
- }
- if (!m->fwdbbs->conn) { /* bad time - no connect method */
- if (Mtrace)
- tcmdprintf ("fwd: skipping '%s' - no connect method\n", m->fwdbbs->name);
- /* This section keeps a inactive BBS from blocking others in a subchannel */
- k = indexFwdBbs (m->fwdbbs->name);
- if (k != NUMFWDBBS)
- MyFwds[k].processed = 1;
- fwdfree (&m->fwdbbs);
- continue;
- }
- strncpy (m->name, m->fwdbbs->name, 20);
- *poll = m->fwdbbs->poll;
- if (m->special)
- *poll = 1;
- retval = 1;
- done = 1;
-
- } while (!done);
- return retval;
- }
-
-
-
- int
- dombtimer (int argc, char *argv[], void *p OPTIONAL)
- {
- if (argc < 2) {
- tprintf (forwardingtimer, read_timer (&fwdtimer) / 1000L, dur_timer (&fwdtimer) / 1000L);
- return 0;
- }
- stop_timer (&fwdtimer); /* just in case */
- fwdtimer.func = (void (*)(void *)) fwdtick; /* what to call on timeout */
- fwdtimer.arg = NULL; /* dummy value */
- set_timer (&fwdtimer, atol (argv[1]) * 1000L); /* set timer duration */
- start_detached_timer (&fwdtimer);/* fire it up */
- return 0;
- }
-
-
-
- int
- dombkick (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- fwdtick (NULL);
- return 0;
- }
-
-
-
- /* MDMII: fwdproc is the old fwdtick. But, since it can call kpause, which is
- * very very bad for timer functions :-( this has been converted to a server.
- */
- static void
- fwdtick (void *v OPTIONAL)
- {
- start_detached_timer (&fwdtimer);/* and restart the timer */
- checkforALTs ();
- (void) forwardreset (0, 0, 0);
- if (FWDmode)
- if (newproc ("forward daemon", 2048, fwdproc, 0, NULL, NULL, 0) == NULLPROC)
- log (-1, nostart);
- }
-
-
-
- static void
- checkoneALT (char *name)
- {
- long bid, pos = 0;
- struct fwdbbs *f;
- struct arealist *a;
- struct altlist *alt;
- char buf[256], *cp;
- FILE *fp;
- time_t now, then;
- long size;
- int nummsgs;
-
- (void) time (&now);
- f = fwdread (name, 1);
- if (f == NULLFWDBBS) /* shouldn't happen */
- return;
-
- /* look at each area for this bbs */
- for (a = f->areas; a; a = a->next) {
-
- /* if there are no alternates for this area, skip it */
- if (!a->alternates)
- continue;
-
- /* now check to see if the *.fwd file exists */
- sprintf (buf, "%s/%s", Mailspool, f->name);
- (void) nntp_name_expansion (buf);
- strcat (buf, ".fwd");
- (void) strlwr (buf);
- if ((fp = fopen (buf, UPDATE_TEXT)) == NULLFILE)
- continue; /* nope, skip it */
-
- nummsgs = 0;
- /* check every message not already forwarded or sent to an alt */
- while (pos = ftell (fp), fgets (buf, 255, fp)) {
- /* if forwarded or passed to an alt, skip it */
- if (*buf == '*' || *buf == '-')
- continue;
- /* if not this area, skip it */
- if (strnicmp (&buf[1], a->name, strlen (a->name))) {
- nummsgs++;
- continue;
- }
- if ((cp = strchr (&buf[1], ' ')) == NULLCHAR)
- continue; /* syntax error */
- /* get internal id number of message */
- bid = atol (++cp);
- if ((cp = strchr (cp, ' ')) == NULLCHAR)
- continue; /* syntax error */
- /* get original timestamp */
- then = atol (++cp);
- if ((cp = strchr (cp, ' ')) == NULLCHAR)
- continue; /* syntax error */
- /* get original timestamp */
- size = atol (++cp);
- for (alt = a->alternates; alt; alt = alt->next) {
- /* time to send to this alt? */
- if ((then + (alt->minutes * 60)) > now) {
- nummsgs++;
- continue; /* nope */
- }
- /* send it to the alt bbs's .fwd file */
- updateFwd (alt->name, a->name, bid, size);
- mark_forwarded (fp, pos, '-');
- if (Mtrace)
- tcmdprintf (queueing, bid, f->name, alt->name);
- log (-1, queueing, bid, f->name, alt->name);
- }
- }
- (void) fclose (fp);
- if (!nummsgs) {
- sprintf (buf, "%s/%s", Mailspool, f->name);
- (void) nntp_name_expansion (buf);
- strcat (buf, ".fwd");
- (void) strlwr (buf);
- (void) remove (buf);
- }
- }
- fwdfree (&f);
- }
-
-
-
- void
- checkforALTs (void)
- {
- int k;
-
- ReadFwdBbs (); /* just in case */
-
- /* for each BBS in the forward.bbs file */
- for (k = 0; k < Numfwds; k++)
- checkoneALT (MyFwds[k].name);
-
- freeareas ();
- }
-
-
-
- int
- forwardreset (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- int k;
-
- for (k = 0; k < NUMFWDBBS; k++)
- MyFwds[k].processed = 0;
- return 0;
- }
-
-
-
- /* called when the forward timer expires or explicitly by dombkick() */
- void
- fwdproc (int nerf, void *v1, void *v2 OPTIONAL)
- {
- struct mbx *m;
- int poll, k;
- char name[256];
- time_t t;
- int doneit = 0;
- char *bbsname = NULLCHAR;
- int bbsindex = 0;
- int skip;
-
- if (MBXMaintMode && MBXMaint) {
- if (Mtrace)
- tcmdprintf (delayedmaintenance);
- return;
- }
- if (v1)
- bbsname = strdup (v1);
- if (Mtrace)
- tcmdprintf (started);
- if ((m = newmbx (1)) == NULLMBX) {
- if (Mtrace)
- tcmdprintf (unabletostart);
- return;
- }
- (void) time (&t);
- m->special = (char) nerf; /* non-zero, if forced or exported connect */
- m->logontime = (long) t;
- m->user = Curproc->output;
- m->name[0] = 0;
- m->state = MBX_TRYING;
- lastSessionSkipped = 0;
- while (fwdanybbs (m, &poll, &bbsindex)) {
- bbsindex++;
-
- if (Mtrace)
- tcmdprintf (examining, m->name);
- kwait (NULL);
- if (isconnbbs (m)) {
- /* already connected to this BBS, skip it */
- if (Mtrace)
- tcmdprintf (alreadyconnected, m->name);
- goto skipped;
- }
- kwait (NULL);
- if (bbsname && stricmp (m->name, bbsname))
- goto skipped;
-
- /* If we poll, there is no need to check message area, since this
- * is also done later. It will speed things up here - WG7J
- */
- if (!poll) { /* don't need if polling */
- sprintf (name, "%s/%s.fwd", Mailspool, m->name);
- (void) strlwr (name);
- if (Mtrace)
- tcmdprintf (checkingforfile, name);
- }
- skip = 0;
- k = indexFwdBbs (m->name);
- #if 1
- if (!m->special && m->fwdbbs->minidle && k != NUMFWDBBS && MyFwds[k].lastactivity && (MyFwds[k].lastactivity + (time_t) m->fwdbbs->minidle) > t)
- skip = 1;
- #endif
- /* This section keeps a dead BBS from blocking other in a subchannel */
- if (poll || !uselessconnect (m, name)) {
- if (checksubchannel (m, 0)) { /* maxed out */
- lastSessionSkipped = 1;
- goto skipped;
- }
- if (k != NUMFWDBBS) {
- if (MyFwds[k].processed) {
- #if 0
- int chk;
-
- for (chk = 0; chk < NUMFWDBBS; chk++) {
- if (MyFwds[k].subchannel == MyFwds[chk].subchannel && MyFwds[chk].processed == 0)
- #endif
- goto skipped;
- #if 0
- }
- #endif
- } else
- MyFwds[k].processed = 1;
- }
- if (!strnicmp (m->fwdbbs->conn, "incoming", strlen (m->fwdbbs->conn))) {
- /* it is an incoming PBBS, only */
- if (Mtrace)
- tcmdprintf ("fwd: skipping incoming-only: %s\n", m->name);
- goto skipped;
- }
- if (skip || checksubchannel (m, 1))
- goto skipped;
-
- if (Mtrace)
- tcmdprintf ("fwd: to %s\n", m->name);
-
- sprintf (m->line, "PBBS forwarding: %s", m->name);
- (void) newproc (m->line, 3072, startfwd, (int) m->subchannel | (m->special << 8), (void *) 0, (void *) strdup (m->name), 0); /*lint !e701 */
- m->subchannel = NOSUBCHANNEL;
- kwait (NULL);
- } else {
- /* not polling and we have nothing, mark us as done */
- if (k != NUMFWDBBS)
- MyFwds[k].processed = 1;
- }
- if (nerf) {
- doneit = 1;
- break;
- }
- skipped:if (nerf && doneit)
- break;
- }
- m->state = MBX_FORWARD;
- if (lastSessionSkipped == 0)
- (void) forwardreset (0, NULLCHARP, 0);
- if (bbsname)
- free (bbsname);
- exitbbs (m);
- }
-
-
-
- /* returns 1 if m->name matches the name of another connected mailbox. */
- static int
- isconnbbs (struct mbx *m)
- {
- int i;
-
- for (i = 0; i < NUMMBX; ++i)
- if (Mbox[i] != NULLMBX && Mbox[i] != m &&
- (stricmp (m->name, Mbox[i]->name) == 0) &&
- (Mbox[i]->sid & MBX_SID))
- return 1;
- return 0;
- }
-
-
-
- /* code to support setting the time of TNC PMS's that request it */
- static int
- fwd_clockset (struct mbx *m)
- {
- time_t now;
- struct tm *t;
-
- if ((m->sid & MBX_CLOCK) && (!m->fwdbbs->noclockset)) {
- /* send the clock set command to the TNC */
- now = time ((time_t *) 0);
- now += (((long) m->fwdbbs->clockoffset) * 3600L);
- t = localtime (&now);
- usprintf (m->user, "C %02d%02d%02d %02d%02d\n", t->tm_year,
- t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min);
- usflush (m->user);
- for (;;) {
- if (recvline (m->user, (unsigned char *) m->line, MBXLINE) == -1)
- return -1;
- if (ISPROMPT (m->line))
- break;
- }
- }
- return 0;
- }
-
-
-
- /* possible commands on the command line in the forwarding file */
- static struct cmds cfwdcmds[] =
- {
- #ifdef AX25
- { "ax25", openconn, 0, 0, NULLCHAR },
- { "connect", openconn, 0, 0, NULLCHAR },
- #endif
- #ifdef BBSEXPORT
- { "export", openconn, 0, 0, NULLCHAR },
- #endif
- { "fbbtelnet", openconn, 0, 0, NULLCHAR },
- { "incoming", openconn, 0, 0, NULLCHAR },
- #ifdef NETROM
- { "netrom", openconn, 0, 0, NULLCHAR },
- #endif
- { "tcp", openconn, 0, 0, NULLCHAR },
- { "telnet", openconn, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
-
- static void
- fwdcleanup (struct mbx *m, const char *string)
- {
- int k;
- char *thisname;
-
- thisname = fwd_bbsname (m);
- if (Mtrace && string)
- tcmdprintf (string, thisname);
- log (-1, (string) ? string : forwardingcomplete, thisname);
-
- /* This section marks the last fwd session time */
- k = indexFwdBbs (thisname);
- if (k != NUMFWDBBS) {
- if (m->sid & MBX_SENTSID || m->fwdbbs->alwaysupdate) {
- MyFwds[k].laston = time (NULL);
- smtptick(NULL); /* kick the smtp server, just in case */
- }
- MyFwds[k].lastactivity = time (NULL);
- }
- releasesubchannel (m);
- exitbbs (m);
- if (lastSessionSkipped)
- fwdtick (NULL);
- }
-
-
-
-
- /* this function tells us whether the forwarding session has
- gone too long */
- int
- cutofffwding (struct mbx *m)
- {
- time_t now;
-
- /* if not initialized, or limittime disabled, return okay */
- if (!m || m->quickfile || !m->fwdbbs || !m->fwdbbs->limittime)
- return 0;
-
- /* if no starttime (incoming session), initialize it, and return okay */
- if (m->fwdbbs->starttime) {
- (void) time (&m->fwdbbs->starttime);
- return 0;
- }
-
- /* else, get current time, and see if limittime reached */
- (void) time (&now);
- if ((now - m->fwdbbs->starttime) > m->fwdbbs->limittime)
- return 1;
- else
- return 0;
- }
-
-
-
- /* this function is called whenever the forwarding timer expires */
- static void
- startfwd (int a, void *v1 OPTIONAL, void *v2)
- {
- struct mbx *m;
- int32 timeout;
- int rval, retval;
- time_t t;
- int poll;
- struct fscript *s;
- int connectnum = 1;
- int err;
- char export[7];
- #ifdef LOCK
- int lockedstate;
- #endif
-
- server_disconnect_io ();
- poll = a / 256;
- a %= 256;
- if ((m = newmbx (1)) == NULLMBX) {
- free ((char *) v2);
- if (a != NOSUBCHANNEL)
- subchannels[a].used--;
- return;
- }
- m->subchannel = a;
- #ifdef STATS_USE
- STATS_adduse (0);
- #endif
- (void) time (&t);
- m->special = (char) ((poll == 1) ? poll : 0);
- m->logontime = (long) t;
- strncpy (m->name, (char *) v2, 20);
-
- strcpy (export, "export");
-
- free ((char *) v2);
- m->state = MBX_TRYING;
- for (;;) {
- fwdfree (&m->fwdbbs);
- m->fwdbbs = fwdread (m->name, connectnum);
- if (m->fwdbbs->conn == NULLCHAR) { /* shouldn't happen */
- fwdcleanup (m, "fwd: error in forward.bbs for %s\n");
- return;
- }
- if (poll == 1 && !stricmp (m->fwdbbs->conn, export))
- poll = 2;
- if (Mtrace)
- tcmdprintf ("fwd: Attempting connect #%d to %s: '%s'\n", connectnum, m->name, (poll == 2) ? export : m->fwdbbs->conn);
-
- #ifdef LOCK
- lockedstate = Kblocked;
- Kblocked = 0;
- #endif
- /* open the connection, m->user will be the new socket */
- retval = cmdparse (cfwdcmds, (poll == 2) ? export : m->fwdbbs->conn, (void *) m);
- #ifdef LOCK
- Kblocked = lockedstate;
- #endif
- if (retval != -1)
- break;
-
- if (connectnum++ == m->fwdbbs->maxtries) {
- checkoneALT (m->name);
- fwdcleanup (m, "fwd: unknown connect protocol or TRIES exceeded to %s\n");
- return;
- }
- if (Mtrace)
- tcmdprintf (connectionfailed, m->name, connectnum - 1);
- }
- m->state = MBX_FORWARD;
- if (m->user)
- (void) sockowner (m->user, Curproc);
- close_s (Curproc->output);
- close_s (Curproc->input);
- /* m->user will be closed automatically when this process exits */
- Curproc->output = Curproc->input = m->user;
- /* We'll do our own flushing right before we read input */
- kwait (NULL);
- #ifdef BBSEXPORT
- if (m->user)
- #endif
- (void) setflush (m->user, -1);
-
- #if 0
- if (fwdinit (m, connectnum) == -1) {
- /* it is probably not the right time to forward anymore */
- fwdcleanup (m, NULLCHAR);
- return;
- }
- #endif
- #ifdef BBSEXPORT
- if (!m->user) {
- m->sid = (MBX_SID | MBX_MID | MBX_HIER_SID);
- #if 0
- if (!m->special)
- #endif
- (void) dorevfwd (0, NULL, (void *) m);
- (void) fclose (m->quickfile);
- fwdcleanup (m, NULLCHAR);
- close_s (Curproc->output);
- return;
- }
- #endif
-
- /* read the connect script. Lines starting with a dot will be sent
- * to the remote BBS.
- */
- for (s = m->fwdbbs->script; s; s = s->next) {
- if (s->linetype == SCRIPT_SID) {
- strncpy (m->line, s->string, 20);
- (void) mbx_parse (m); /* interpret it */
- /* now automatically send OUR SID */
- #ifdef MBFWD
- mbx_SendSid (m);
- #endif
- continue;
- }
- if (s->linetype == SCRIPT_SEND) {
- tprintf (s->string);
- tputc ('\n');
- if (Mtrace)
- tcmdprintf ("fwd: %s > %s\n", m->name, s->string);
- } else if (s->linetype == SCRIPT_WAIT) {
- char good[80], bad[80], *myptr;
- int checkbad = 0;
-
- bad[0] = 0;
- strncpy (good, s->string, 80);
- if ((myptr = strchr (good, '|')) != NULLCHAR) {
- /* negative search string found */
- *myptr++ = 0;
- strncpy (bad, myptr, 80);
- checkbad = 1;
- }
- timeout = s->timeout;
- if (timeout) /* if a valid conversion */
- timeout *= 1000; /* in ms ! */
- if (Mtrace)
- tcmdprintf ("fwd: %s, wait %d < %s\n", m->name, s->timeout, s->string);
-
- /* Now do the actual response interpretations */
- kalarm (timeout);
- for (;;) {
-
- rval = recvline (m->user, (unsigned char *) m->line, MBXLINE);
- if (Mtrace) {
- tcmdprintf ("fwd: %s, rx %d", m->name, rval);
- if (rval >= 0)
- tcmdprintf (", %s", m->line);
- else
- tcmdprintf ("\n");
- }
- /* Did we timeout, or connection disappear ? */
- if (rval < 0) {
- fwdcleanup (m, "fwd: %s, aborted!\n");
- return;
- }
- if (strstr (m->line, good))
- break;
- if (checkbad && strstr (m->line, bad)) {
- fwdcleanup (m, "fwd: %s, aborted!\n");
- return;
- }
- }
- kalarm (0L);
- } else /* must be the end of the script */
- goto go_on;
-
- usflush (m->user); /* send it, if any */
- }
- /* Now we've past all in-between stuff, go talk to the bbs ! */
- go_on:
- usflush (m->user);
- if (Mtrace)
- tcmdprintf (scriptdone, m->name);
-
- /* read the initial output from the bbs, looking for the SID */
- for (;;) {
- timeout = 120 * 1000L; /* wait up to 2 minutes for each response line */
- if (Mtrace)
- tcmdprintf (waitingfor, m->name, timeout / 1000, ">");
- kalarm (timeout);
- rval = recvline (m->user, (unsigned char *) m->line, MBXLINE);
- kalarm (0L);
- if (rval == -1) {
- fwdcleanup (m, NULLCHAR);
- return;
- }
- if (Mtrace)
- tcmdprintf ("fwd: %s < %s", m->name, m->line);
- if (ISPROMPT (m->line))
- break;
- if (*m->line == '[') { /* parse the SID */
- rip (m->line);
- (void) mbx_parse (m);
- continue;
- }
- }
-
- /* Now sync the two ends as telnet password messes them up */
- if (socklen (m->user, 0)) /* discard any remaining input */
- (void) recv_mbuf (m->user, NULL, 0, NULLCHAR, 0);
-
- /* set the start time, for cutofffwding() */
- (void) time (&m->fwdbbs->starttime);
-
- /* send our SID if the peer announced its SID */
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD)) {
- /* All we do is send a SID and start forwarding. */
- /* The remote box doesn't send any OK prompts. */
-
- /* Send [xxxx] string. */
- mbx_SendSid (m);
- if (!(m->sid & MBX_FBBFWD)) /* since mbx_SendSid can change this */
- goto adjust;
- if (fwd_clockset (m) != -1)
- /* start the actual forwarding */
- (void) dofbbfwd (0, NULL, (void *) m);
- fwdcleanup (m, NULLCHAR);
- return;
- } else
- #endif
- if (m->sid & MBX_SID) {
- mbx_SendSid (m);
- #ifdef FBBFWD
- adjust:
- #endif
- if (fwd_clockset (m) == -1) {
- fwdcleanup (m, NULLCHAR);
- return;
- }
- usflush (m->user);
- for (;;) {
- if (recvline (m->user, (unsigned char *) m->line, MBXLINE) == -1) {
- fwdcleanup (m, NULLCHAR);
- return;
- }
- if (ISPROMPT (m->line))
- break;
- }
- } else {
- /* if the sysop has told us that this is a dumb PMS, then
- we will ignore the lack of a SID */
- if (!m->fwdbbs->dumbpms) {
- /* if we get here and have NOT received a SID, we have a
- screwed up forwarding script, or the remote has a SERIOUS
- breach of the forwarding protocol. Since we do NOT know the
- capabilities of the remote machine, we abort! */
- log (m->user, nosidfound, fwd_bbsname(m));
- log (m->user, nosidfound2);
- tcmdprintf (nosidfound, fwd_bbsname(m));
- tcmdprintf ("\n");
- tcmdprintf (nosidfound2);
- tcmdprintf ("\n");
- fwdcleanup (m, NULLCHAR);
- return;
- }
- }
-
- /* start the actual forwarding */
- #ifdef FBBFWD
- if (Mfbb && (m->sid & MBX_FBBFWD)) {
- (void) dofbbfwd (0, NULL, (void *) m);
- fwdcleanup (m, NULLCHAR);
- return;
- } else
- #endif
- #ifdef XFWD
- if (MXfwd && (m->sid & MBX_XFWD)) {
- (void) doxfwd (0, NULL, (void *) m);
- fwdcleanup (m, NULLCHAR);
- return;
- } else
- #endif
- m->usecolor = (char) FWDinreverse; /* default to this, each entry can override */
- err = dorevfwd (0, NULL, (void *) m);
- /* if no incoming reverse, just disconnect, else */
- /* ask for reverse forwarding or just disconnect */
- if (err || m->usecolor == 0 || ((m->sid & MBX_SID) && tputs ("F>\n") == -1) ||
- (m->sid & MBX_SID) == 0) {
- fwdcleanup (m, NULLCHAR);
- close_s (Curproc->output);
- return;
- }
- m->usecolor = 0;
- usflush (m->user);
- /* parse the commands that are are received during reverse
- * forwarding.
- */
- while (recvline (m->user, (unsigned char *) m->line, MBXLINE) > 0) {
- if (cutofffwding (m))
- break;
- if (m->privs & EXCLUDED_CMD)
- break;
- rip (m->line);
- if ((rval = mbx_parse (m)) < 0)
- /* -2 == "*** Done" rec'd, -1 => cmd not in Mbcmds, or other err) */
- break;
- if (rval && BBSdump) /* we dump for all unknowns! */
- break;
- if (m->privs & EXCLUDED_CMD)
- break;
- if (MBXMaintMode && MBXMaint)
- break;
- tputs ("F>\n");
- usflush (m->user);
- }
- (void) domboxbye (0, NULL, m);
-
- if ((m->sid & MBX_SID) && m->mysize)
- smtptick (NULL);/* wake SMTP to send that mail */
- fwdcleanup (m, NULLCHAR);
- usflush (Curproc->output);
- kpause (500L);
- close_s (Curproc->output);
- }
-
-
-
- /* open a network connection based upon information in the cc line.
- * m->user is set to the socket number.
- */
- static int
- openconn (int argc, char *argv[], void *p)
- {
- struct mbx *m;
- char sock[MAXSOCKSIZE];
- union sp sp;
- int len;
- #ifdef NETROM
- char alias[AXBUF];
- struct nrroute_tab *rp;
- #endif
- #ifdef BBSEXPORT
- char namebuf[512];
- #endif
-
- m = (struct mbx *) p;
- sp.p = sock;
- #ifdef BBSEXPORT
- if (argv[0][0] != 'e' && argc < 2)
- #else
- if (argc < 2)
- #endif
- return -1;
- switch (*argv[0]) {
- case 'f':
- m->fwdbbs->limittype &= ~FWDTYPE_XFWD;
- /* fall through */
- case 't':
- sp.in->sin_family = AF_INET;
- {
- if ((sp.in->sin_addr.s_addr = resolve (argv[1])) == 0)
- return -1;
- /* get the optional port number */
- if (argc > 2)
- sp.in->sin_port = (int16) atoip (argv[2]);
- else
- sp.in->sin_port = IPPORT_TELNET;
- }
- if ((m->user = socket (AF_INET, SOCK_STREAM, 0)) == -1)
- return -1;
- len = sizeof (*sp.in);
- m->family = AF_INET; /*So the user list will be correct! - WG7J */
- break;
- #ifdef AX25
- case 'a':
- case 'c': /* allow 'c' for 'connect' as well */
- if (argc < 3)
- return -1;
- sp.ax->sax_family = AF_AX25;
- if (if_lookup (argv[1]) == NULLIF) {
- if (Mtrace)
- tcmdprintf (badax25iface, argv[1], m->name);
- log (-1, badax25iface, argv[1], m->name);
- return -1;
- }
- if ((m->user = socket (AF_AX25, SOCK_STREAM, 0)) == -1)
- return -1;
- if (*FWDCall) {
- memcpy (sp.ax->ax25_addr, FWDCall, AXALEN);
- (void) bind (m->user, (char *) sp.ax, sizeof (struct sockaddr_ax));
- }
- strncpy (sp.ax->iface, argv[1], ILEN - 1); /* the interface name */
- (void) setcall (sp.ax->ax25_addr, argv[2]); /* the remote callsign */
-
- /* no digipeaters for now, use the "ax25 route add" command */
- /* this code attempts to correct this longstanding limitation */
- if (argc > 3) {
- int didrose = 0, i;
- char tmp[AXBUF];
-
- if (!strcmp (argv[3], "@")) {
- didrose = 1;
- argv[3] = strdup (pax25 (tmp, AXRosecall));
- }
- i = connect_filt (argc, argv, sp.ax->ax25_addr, if_lookup (argv[1]), AX_SETUP);
- if (didrose)
- free (argv[3]);
- if (i == 0)
- return -1;
- }
- len = sizeof (*sp.ax);
- m->family = AF_AX25; /*So the user list will be correct! - WG7J */
- break;
- #endif /* AX25 */
- #ifdef NETROM
- case 'n':
- /* See if the requested destination could be an alias, and
- * use it if it is. Otherwise assume it is an AX.25
- * address.
- */
- (void) putalias (alias, argv[1], 0);
- (void) strupr (argv[1]);
- if ((rp = find_nrboth (alias, argv[1])) == NULLNRRTAB) {
- if (Mtrace)
- tcmdprintf (Netromunavailable, argv[1]);
- return -1;
- }
- /* Setup the local side of the connection */
- sp.nr->nr_family = AF_NETROM;
- len = sizeof (*sp.nr);
- if ((m->user = socket (AF_NETROM, SOCK_SEQPACKET, 0)) == -1) {
- if (Mtrace)
- tcmdprintf (Netromsocket, argv[1]);
-
- return -1;
- }
- memcpy (sp.nr->nr_addr.user, Nr4user, AXALEN);
- memcpy (sp.nr->nr_addr.node, Nr_iface->hwaddr, AXALEN);
- (void) bind (m->user, sp.p, len);
-
- /* Now the remote side */
- memcpy (sp.nr->nr_addr.node, rp->call, AXALEN);
- /* The user callsign of the remote station is never
- * used by NET/ROM, but it is needed for the psocket() call.
- */
- memcpy (sp.nr->nr_addr.user, rp->call, AXALEN);
-
- m->family = AF_NETROM; /*So the user list will be correct! - WG7J */
- break;
- #endif /* NETROM */
- #ifdef BBSEXPORT
- case 'e':
- /* open current export file */
- sprintf (namebuf, "%s/%s.exp", EXPORTDir, m->name);
- m->quickfile = fopen (namebuf, APPEND_TEXT);
- if (m->quickfile) {
- m->user = 0;
- m->family = AF_LOCAL;
- return 0;
- } /* else, fall through */
- #endif
- case 'i': /* incoming only, no outbound */
- default:
- return -1;
- }
- (void) sockmode (m->user, SOCK_ASCII);
- if (*argv[0] == 'f')
- (void) seteol (m->user, "\r\n");
-
- if (connect (m->user, sp.p, len) == -1) {
- log (m->user, forwardfailed, sockerr (m->user), errno);
- close_s (m->user);
- return -1;
- }
- return m->user;
- }
-
-
-
- void
- forwardingSummary ()
- {
- int k, first = 1, i;
- char curstate, curtype;
- register FILE *fp;
- char buf[100], *cp;
- int totbul = 0, totper = 0, bul, per;
- long size, totsize = 0;
-
- ReadFwdBbs (); /* just in case */
- for (k = 0; k < Numfwds; k++) {
- sprintf (buf, "%s/%s.fwd", Mailspool, MyFwds[k].name);
- (void) strlwr (buf);
- per = bul = 0;
- size = 0;
- if ((fp = fopen (buf, READ_TEXT)) != NULLFILE) {
- while (fgets (buf, sizeof (buf), fp) != NULLCHAR)
- if (*buf != '*' && *buf != '-') {
- cp = strchr (&buf[1], ' ');
- if (cp) {
- *cp++ = 0;
- if (isarea (&buf[1]))
- bul++;
- else
- per++;
- cp = strrchr (cp, ' ');
- if (cp)
- size += atol (++cp);
- }
- }
- (void) fclose (fp);
- }
- totsize += size;
- if (size)
- size = ((size + 513) / 1024);
- if (first) {
- tputc ('\n');
- first = 0;
- }
- curstate = ':';
- curtype = ' ';
- for (i = 0; i < NUMMBX; ++i) {
- if (Mbox[i] == NULLMBX)
- continue;
- if (!stricmp (Mbox[i]->name, MyFwds[k].name) && Mbox[i]->state >= MBX_SUBJ && Mbox[i]->state <= MBX_FORWARD) {
- curstate = '*';
- #ifdef XFWD
- if (MXfwd && Mbox[i]->sid & MBX_XFWD)
- curtype = 'X';
- #endif
- #ifdef FBBFWD
- if (Mfbb && Mbox[i]->sid & MBX_FBBFWD)
- curtype = 'F';
- #endif
- break;
- }
- }
-
- tprintf ("Queued for forwarding to %-10.10s%c%c Bulletins/Personal (%5d/%-5d) %-ldK\n", MyFwds[k].name, curstate, curtype, bul, per, size);
- totbul += bul;
- totper += per;
- }
- if (k) {
- if (totsize)
- totsize = ((totsize + 513) / 1024);
- for (k = 0; k < 78; k++)
- tputc ('-');
- tprintf ("\nTotal messages to forward : Bulletins/Personal (%5d/%-5d) %-ldK\n\n", totbul, totper, totsize);
- } else
- tputs ("You have no BBS's in your 'forward.bbs' file!\n");
- }
-
-
-
- int
- AREAlookup (char *area, int theindex)
- {
- int retval = 0;
- struct fwdbbs *f = NULLFWDBBS;
- struct arealist *a;
- int cur = 0;
-
- for (cur = 0; cur <= theindex; cur++) {
- f = fwdread (NULLCHAR, cur);
- if (f == NULLFWDBBS)
- return retval;
- if (cur != theindex)
- fwdfree (&f);
- }
- if (f) {
- a = f->areas;
- while (a) {
- if (!stricmp (a->name, area)) {
- retval = (!a->isALT);
- break;
- }
- a = a->next;
- }
- fwdfree (&f);
- }
- return retval;
- }
-
- #endif /*MBFWD*/
-
-
-
- void
- fwdlockit (char *name)
- {
- while (mlock (Mailspool, name))
- kpause (1000L); /* Wait one second and try again */
- }
-
-
-
- void
- fwdunlockit (char *name)
- {
- rmlock (Mailspool, name);
- }
-